/*
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations
 * under the License.
 * 
 * The Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
 *
 * The Initial Developer of the Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
 * Portions created by Mark A. Kobold are Copyright (C) 2000-2007. All Rights Reserved.
 *
 * Contributor(s): 
 *  Mark A. Kobold [mkobold <at> isqlviewer <dot> com].
 *  
 * If you didn't download this code from the following link, you should check
 * if you aren't using an obsolete version: http://www.isqlviewer.com
 */
package org.isqlviewer.swing.table;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

import org.isqlviewer.util.LocalMessages;

/**
 * An simple general purpose table model for Strings from various sources.
 * <p>
 * This implementation of the TableModel interface is mainly for general use for Properties and other Map type objects
 * as well as String only ResultSet objects.
 * 
 * @author Markus A. Kobold &lt;mkobold at sprintpcs dot com&gt;
 * @version 1.0
 */
public class PropertyTableModel extends EnhancedTableModel {

    private static final String RESOURCE_BUNDLE = "org.isqlviewer.swing.ResourceBundle";
    private static final LocalMessages messages = new LocalMessages(RESOURCE_BUNDLE);
    private boolean isEditable = false;

    public PropertyTableModel() {

        this(null);
    }

    public PropertyTableModel(Map<String, Object> table) {

        setData(table);
        setColumns(new String[]{messages.format("PropertyKey.ColumnHeader"),
                                messages.format("PropertyValue.ColumnHeader")});
    }

    @Override
    public boolean isCellEditable(int row, int col) {

        return isEditable;
    }

    /**
     * Applies a Map objects as the TableModel.
     * <p>
     * This will create a two column table model with one column being the keys, and the other being the values for each
     * key.
     * <p>
     * This will set the model type to TYPE_MAP, also any prexisting data will be cleared.
     * 
     * @see #setData(ResultSet)
     * @param set of data to load this table model with.
     */
    public synchronized void setData(Map<String, ? extends Object> table) {

        clear();
        Iterator< ? extends Map.Entry<String, ? extends Object>> i = table.entrySet().iterator();
        ArrayList<String> row = new ArrayList<String>(2);
        while (i.hasNext()) {
            Map.Entry<String, ? extends Object> entry = i.next();
            if (entry != null) {
                row.set(0, entry.getKey());
                String text = entry.getValue() == null ? "" : entry.getValue().toString();
                row.set(1, text);
                addRow(row);
                row.clear();
            }
        }
        fireTableStructureChanged();
    }

    /**
     * Toggles the ability to edit this table model.
     * <p>
     * Since this is mainly for using this table model from a Map of strings, in paticular the properties object.
     * 
     * @param f toggles the ability to edit the underlying data.
     */
    public synchronized void allowEditing(boolean f) {

        isEditable = f;
    }

    /**
     * Creates a properties object from the first two columns.
     * <p>
     * If this TableModel doesn't have two columns an empty properties object will be returned.
     * 
     * @return properties object from the first two columns of the model.
     */
    public Properties toProperties() {

        Properties props = new Properties();
        if (getColumnCount() >= 2) {
            synchronized (dataStore) {
                Iterator itr = dataStore.iterator();
                while (itr.hasNext()) {
                    try {
                        ArrayList row = (ArrayList) itr.next();
                        String key = (String) row.get(0);
                        String value = (String) row.get(1);
                        props.setProperty(key, value);
                    } catch (NullPointerException npe) {
                        continue;
                    } catch (ClassCastException cce) {
                        continue;
                    } catch (Throwable t) {
                        throw new RuntimeException(t);
                    }
                }
            }
        }
        return props;
    }

}